package com.xinqi.modules.homework.homework.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinqi.common.base.enums.YesNoEnum;
import com.xinqi.common.base.enums.YesNoNumberEnum;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.base.response.PageInfo;
import com.xinqi.common.base.response.Param;
import com.xinqi.common.base.response.R;
import com.xinqi.common.base.utils.json.JSON;
import com.xinqi.common.base.utils.spring.Spring;
import com.xinqi.common.core.constant.HomeworkConstants;
import com.xinqi.common.core.enums.*;
import com.xinqi.common.core.utils.MessageUtils;
import com.xinqi.common.mybatis.data.service.impl.BaseServiceImpl;
import com.xinqi.common.mybatis.utils.Pages;
import com.xinqi.common.mybatis.utils.Queries;
import com.xinqi.common.satoken.utils.LoginHelper;
import com.xinqi.modules.course.classmenu.client.ClassMenuClient;
import com.xinqi.modules.course.clazz.client.ClassGroupStudentClient;
import com.xinqi.modules.course.clazz.client.ClassStudentClient;
import com.xinqi.modules.course.clazz.dto.rsp.ClassGroupStudentResultDTO;
import com.xinqi.modules.course.clazz.dto.rsp.ClassStudentResultDTO;
import com.xinqi.modules.homework.homework.assistant.AssistantListen;
import com.xinqi.modules.homework.homework.convert.CourseHomeworkFileConvert;
import com.xinqi.modules.homework.homework.convert.CourseHomeworkRecordConvert;
import com.xinqi.modules.homework.homework.convert.CourseHomeworkStudentLogConvert;
import com.xinqi.modules.homework.homework.domain.CourseHomeworkEntity;
import com.xinqi.modules.homework.homework.domain.CourseHomeworkFileEntity;
import com.xinqi.modules.homework.homework.domain.CourseHomeworkRecordEntity;
import com.xinqi.modules.homework.homework.domain.CourseHomeworkStudentLogEntity;
import com.xinqi.modules.homework.homework.dto.req.*;
import com.xinqi.modules.homework.homework.dto.rsp.*;
import com.xinqi.modules.homework.homework.mapper.CourseHomeworkMapper;
import com.xinqi.modules.homework.homework.mapper.CourseHomeworkStudentLogMapper;
import com.xinqi.modules.homework.homework.service.CourseHomeworkFileService;
import com.xinqi.modules.homework.homework.service.CourseHomeworkRecordService;
import com.xinqi.modules.homework.homework.service.CourseHomeworkService;
import com.xinqi.modules.homework.homework.service.CourseHomeworkStudentLogService;
import com.xinqi.modules.homework.homework.thread.SliceHomeworkFileService;
import com.xinqi.modules.homework.homework.utils.MathUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 服务层实现
 *
 * @author: system
 * @date: 2023/03/08
 */
@Service("courseHomeworkStudentLogService")
@RequiredArgsConstructor
@Slf4j
public class CourseHomeworkStudentLogServiceImpl extends BaseServiceImpl<CourseHomeworkStudentLogMapper, CourseHomeworkStudentLogEntity> implements CourseHomeworkStudentLogService {

    private final CourseHomeworkStudentLogConvert courseHomeworkStudentLogConvert;

    private final CourseHomeworkRecordConvert courseHomeworkRecordConvert;
    @Lazy
    private final CourseHomeworkRecordService courseHomeworkRecordService;
    @Lazy
    private final CourseHomeworkFileService courseHomeworkFileService;
    private final CourseHomeworkFileConvert courseHomeworkFileConvert;

    private final SliceHomeworkFileService sliceHomeworkFileService;

    private final CourseHomeworkMapper courseHomeworkMapper;

    @Lazy
    private final CourseHomeworkService courseHomeworkService;
    private final IdentifierGenerator identifierGenerator;

    private final ClassStudentClient classStudentClient;

    private final ClassGroupStudentClient classGroupStudentClient;

    private final ClassMenuClient classMenuClient;

    /**
     * 新奇助手
     */
    private final AssistantListen assistantListen;

    /**
     * 分页查询 列表数据
     */
    @Override
    @DS("slaver")
    public PageInfo<CourseHomeworkStudentResultDTO> homeworkStudentList(Param pageable, CourseHomeworkStudentLogQueryDTO dto) {

        CommonErrors.BAD_REQUEST.check(dto.getClassId() != null, "班级ID不能为空");

        Long userId = LoginHelper.getUserId();
        classStudentClient.checkIsStudent(dto.getClassId(), userId);
        // 获取主学生信息
        ClassStudentResultDTO mainStudent = R.as(classStudentClient.findVirtualClassStudentByClassIdAndUserId(dto.getClassId(), userId));
        if (Objects.nonNull(mainStudent)) {
            dto.setStudentId(mainStudent.getStudentId());
        }

        IPage<CourseHomeworkStudentResultDTO> page = this.baseMapper.homeworkStudentList(Pages.page(pageable), dto);
        page.getRecords().forEach(item -> item.setStudentScore(MathUtils.stripTrailingZeros(item.getStudentScore(), 1)));
        return Pages.convert(page, courseHomeworkStudentLogConvert::convert);
    }

    /**
     * 根据作业内容轮数查询学生作业列表 根据状态
     */
    @Override
    public List<CourseHomeworkStudentInfoResultDTO> homeworkStudentInfoListByStatus(CourseHomeworkStudentBaseDTO dto) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getContentId()), "作业ID不能为空");
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getTimes()), "作业轮数不能为空");
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getType()), "作业状态不能为空");
        List<CourseHomeworkStudentInfoResultDTO> list = this.baseMapper.homeworkStudentInfoListByStatus(dto);
        list.forEach(item -> item.setStudentScore(MathUtils.stripTrailingZeros(item.getStudentScore(), 1)));
        return list;
    }

    /**
     * 根据作业内容轮数查询学生作业详情
     */
    @Override
    public CourseHomeworkStudentListResultDto homeworkStudentInfoList(CourseHomeworkStudentLogQueryDTO dto) {
        //CommonErrors.BAD_REQUEST.check(dto.getClassId() != null, "班级ID不能为空");
        CommonErrors.BAD_REQUEST.check(dto.getContentId() != null, "作业ID不能为空");
        // 获取学生作业记录日志
        CourseHomeworkStudentListResultDto listResultDto = new CourseHomeworkStudentListResultDto();
        dto.setInProgress(HomeWorkRecordStatusEnum.IN_PROGRESS_YES.getCode());
        List<CourseHomeworkStudentInfoResultDTO> studentList = this.baseMapper.homeworkStudentInfoList(dto);
        studentList.forEach(item -> {
            item.setScore(MathUtils.stripTrailingZeros(item.getScore(), 1));
            item.setStudentScore(MathUtils.stripTrailingZeros(item.getStudentScore(), 1));
        });
        listResultDto.setStudentList(studentList);

        // 获取作业轮数信息
        CourseHomeworkTimerResultDTO timerDTO = this.findSubmitStatus(dto.getContentId());
        listResultDto.setTimerList(timerDTO);

        return listResultDto;
    }

    @Override
    public PageInfo<CourseHomeworkStudentInfoResultDTO> homeworkStudentPage(Page<CourseHomeworkStudentInfoResultDTO> page, CourseHomeworkStudentLogQueryDTO dto) {
        CommonErrors.BAD_REQUEST.check(dto.getContentId() != null, "作业ID不能为空");
        // 获取学生作业记录日志
        IPage<CourseHomeworkStudentInfoResultDTO> pageList = this.baseMapper.homeworkStudentPage(page, dto);
        if (CollectionUtils.isNotEmpty(pageList.getRecords())) {
            pageList.getRecords().forEach(item -> {
                item.setScore(MathUtils.stripTrailingZeros(item.getScore(), 1));
                item.setStudentScore(MathUtils.stripTrailingZeros(item.getStudentScore(), 1));
            });
        }

        return Pages.convert(pageList);
    }

    @Override
    public CourseHomeworkTimerResultDTO findSubmitStatus(Long contentId) {
        return this.baseMapper.findSubmitStatus(contentId);
    }

    /**
     * 查询 数据
     */
    @Override
    public List<CourseHomeworkStudentLogResultDTO> find(CourseHomeworkStudentLogQueryDTO query) {
        return this.baseMapper.selectDtoList(wrapper(query), courseHomeworkStudentLogConvert::convert);
    }

    private LambdaQueryWrapper<CourseHomeworkStudentLogEntity> wrapper(CourseHomeworkStudentLogQueryDTO query) {
        LambdaQueryWrapper<CourseHomeworkStudentLogEntity> wrapper = Queries.lambda();
        if (Objects.nonNull(query.getId())) {
            Queries.accept(query.getId(), v -> wrapper.eq(CourseHomeworkStudentLogEntity::getId, v));
        }
        if (Objects.nonNull(query.getContentId())) {
            Queries.accept(query.getContentId(), v -> wrapper.eq(CourseHomeworkStudentLogEntity::getContentId, v));
        }
        if (Objects.nonNull(query.getTimes())) {
            Queries.accept(query.getTimes(), v -> wrapper.eq(CourseHomeworkStudentLogEntity::getTimes, v));
        }
        if (Objects.nonNull(query.getStudentId())) {
            Queries.accept(query.getStudentId(), v -> wrapper.eq(CourseHomeworkStudentLogEntity::getStudentId, v));
        }
        return wrapper;
    }

    /**
     * 根据id查询 数据
     */
    @Override
    public CourseHomeworkStudentLogResultDTO findById(Long id) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(id), ResultConfigEnum.DATA_NOT_EXIST.getDescription());
        CourseHomeworkStudentLogResultDTO resultDTO = this.baseMapper.selectDtoById(id, courseHomeworkStudentLogConvert::convert);

        // 更新为已读
        CourseHomeworkStudentLogUpdateDTO studentLogUpdateDTO = new CourseHomeworkStudentLogUpdateDTO();
        studentLogUpdateDTO.setId(resultDTO.getId());
        this.updateIsRead(studentLogUpdateDTO);

        return resultDTO;
    }

    /**
     * 查询学生提交作业详情
     */
    @Override
    public CourseHomeworkStudentInfoResultDTO findStudentDetail(CourseHomeworkStudentDetailDTO query) {

        // 获取作业详情数据
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(query.getContentId()), MessageUtils.message("course.homework.id.not.blank"));
        CourseHomeworkResultDTO result = courseHomeworkMapper.findDetailById(query.getContentId(), query);
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(result), MessageUtils.message("course.homework.id.not.exit"));

        // 判断是否存在学生ID,不存在获取登录用户ID
        if (Objects.isNull(query.getStudentId())) {
            query.setStudentId(LoginHelper.getUserId());
        }

        CourseHomeworkEntity homework = courseHomeworkMapper.selectById(query.getContentId());

        // 获取主学生信息
        ClassStudentResultDTO mainStudent = R.as(classStudentClient.findVirtualClassStudentByClassIdAndUserId(homework.getClassId(), query.getStudentId()));

        CourseHomeworkStudentLogQueryDTO dto = new CourseHomeworkStudentLogQueryDTO();
        dto.setClassId(homework.getClassId());
        dto.setContentId(query.getContentId());
        dto.setStudentId(mainStudent.getStudentId());
        dto.setTimes(query.getTimes());
        if (Objects.nonNull(query.getRecordId())) {
            dto.setRecordId(query.getRecordId());
        }
        return this.findByParam(dto);
    }

    /**
     * 根据作业参数轮数查询 学生提交作业数据
     */
    @Override
    public CourseHomeworkStudentInfoResultDTO findByParam(CourseHomeworkStudentLogQueryDTO dto) {

        dto.setInProgress(HomeWorkRecordStatusEnum.IN_PROGRESS_YES.getCode());
        CourseHomeworkStudentInfoResultDTO infoResultDTO = this.findStudentInfo(dto);

        if (Objects.nonNull(infoResultDTO)) {
            infoResultDTO.setSubmitFlag(true);
            // 已批赋值 得分
            if (Objects.equals(HomeWorkStudentStatusEnum.APPROVED.getCode(), infoResultDTO.getTaskStatus())) {
                infoResultDTO.setStudentScore(MathUtils.stripTrailingZeros(infoResultDTO.getStudentScore(), 1));
            } else {
                infoResultDTO.setStudentScore(null);
            }

            // 获取主学生信息
            ClassStudentResultDTO mainStudent = R.as(classStudentClient.findVirtualClassStudentByClassIdAndUserId(dto.getClassId(), LoginHelper.getUserId()));

            // 校验学生是否可以提交作业
            boolean flag = this.checkSubmitFlag(infoResultDTO.getContentId(), infoResultDTO.getTimes(), infoResultDTO.getStudentId());
            infoResultDTO.setSubmitFlag(flag);

            //判断是否传recordId(传入只查此记录 不传业务判断显示)
            if (Objects.nonNull(dto.getRecordId())) {
                // 学生端获取 批阅或最新提交信息（已批获取批阅信息，未批获取最新提交信息）
                this.setStudentRecode(infoResultDTO, dto);
            } else {
                if (Objects.nonNull(mainStudent)) {
                    // 更新为已读
                    CourseHomeworkStudentLogUpdateDTO studentLogUpdateDTO = new CourseHomeworkStudentLogUpdateDTO();
                    studentLogUpdateDTO.setId(infoResultDTO.getId());
                    this.updateIsRead(studentLogUpdateDTO);
                    // 学生端获取 批阅或最新提交信息（已批获取批阅信息，未批获取最新提交信息）
                    this.setStudentRecode(infoResultDTO, dto);
                } else {
                    // 更新有新提交标志
                    CourseHomeworkStudentLogUpdateDTO studentLogUpdateDTO = new CourseHomeworkStudentLogUpdateDTO();
                    studentLogUpdateDTO.setId(infoResultDTO.getId());
                    this.updateHandStatus(studentLogUpdateDTO);
                    // 老师端获取 学生提交 记录列表
                    this.setAllRecode(infoResultDTO, dto);
                }
            }
        }

        return infoResultDTO;
    }


    /**
     * 查询最新提交的作业
     */
    private void setLatestRecode(CourseHomeworkStudentInfoResultDTO infoResultDTO, CourseHomeworkStudentLogQueryDTO dto) {
        // 查询 最新一次提交的作业记录
        CourseHomeworkRecordQueryDTO recordQueryDTO = new CourseHomeworkRecordQueryDTO();
        recordQueryDTO.setContentId(dto.getContentId());
        recordQueryDTO.setTimes(dto.getTimes());
        recordQueryDTO.setStudentId(dto.getStudentId());
        recordQueryDTO.setInProgress(HomeWorkRecordStatusEnum.IN_PROGRESS_YES.getCode());
        CourseHomeworkRecordResultDTO recordResultDTO = courseHomeworkRecordService.findByParam(recordQueryDTO);
        if (recordResultDTO != null) {
            infoResultDTO.setRecord(recordResultDTO);
        }
    }

    /**
     * 获取学生提交记录
     * 只记录 提交和批阅的
     */
    private void setStudentRecode(CourseHomeworkStudentInfoResultDTO infoResultDTO, CourseHomeworkStudentLogQueryDTO dto) {
        // 查询 所有提交记录
        CourseHomeworkRecordQueryDTO recordQueryDTO = new CourseHomeworkRecordQueryDTO();
        recordQueryDTO.setContentId(dto.getContentId());
        recordQueryDTO.setTimes(dto.getTimes());
        recordQueryDTO.setStudentId(dto.getStudentId());
        List<CourseHomeworkRecordResultDTO> list = new ArrayList<>();
        if (Objects.nonNull(dto.getRecordId())) {
            CourseHomeworkRecordResultDTO recordResult = courseHomeworkRecordService.findById(dto.getRecordId());
            list.add(recordResult);
        } else {
            list = courseHomeworkRecordService.find(recordQueryDTO);
        }

        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        // 学生状态
        if (Objects.equals(HomeWorkStudentStatusEnum.REPLUSE.getCode(), infoResultDTO.getTaskStatus())) {
            // 打回状态 匹配打回recordId
            CourseHomeworkRecordResultDTO record = list.stream().filter(v ->
                Objects.equals(infoResultDTO.getRecordId(), v.getId())).findFirst().orElse(null);
            if (Objects.nonNull(record)) {
                infoResultDTO.setRecord(record);
            } else {
                infoResultDTO.setRecord(list.get(0));
            }
        } else {
            List<CourseHomeworkRecordResultDTO> approveList = list.stream().filter(v ->
                Objects.equals(HomeWorkStudentStatusEnum.APPROVED.getCode(), v.getTaskStatus())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(approveList)) {
                // 获取日志记录中 保留批阅中的 作业记录
                CourseHomeworkRecordResultDTO record = approveList.stream().filter(v ->
                    Objects.equals(infoResultDTO.getRecordId(), v.getId())).findFirst().orElse(null);
                if (Objects.nonNull(record)) {
                    infoResultDTO.setRecord(record);
                } else {
                    infoResultDTO.setRecord(approveList.get(0));
                }
            } else {
                infoResultDTO.setRecord(list.get(0));
            }
        }
    }

    /**
     * 查询所有提交作业
     * 只记录 提交和批阅的
     */
    private void setAllRecode(CourseHomeworkStudentInfoResultDTO infoResultDTO, CourseHomeworkStudentLogQueryDTO dto) {
        // 查询 最新一次提交的作业记录
        CourseHomeworkRecordQueryDTO recordQueryDTO = new CourseHomeworkRecordQueryDTO();
        recordQueryDTO.setContentId(dto.getContentId());
        recordQueryDTO.setTimes(dto.getTimes());
        recordQueryDTO.setStudentId(dto.getStudentId());

        List<CourseHomeworkRecordResultDTO> list = courseHomeworkRecordService.find(recordQueryDTO);
        list = list.stream().filter(v -> Objects.equals(HomeWorkStudentStatusEnum.SUBMIT.getCode(), v.getTaskStatus())
            || Objects.equals(HomeWorkStudentStatusEnum.APPROVED.getCode(), v.getTaskStatus())).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(list)) {
            infoResultDTO.setRecordList(list);
        }
    }

    /**
     * 获取学生提交作业信息
     *
     * @author dzy
     */
    private CourseHomeworkStudentInfoResultDTO findStudentInfo(CourseHomeworkStudentLogQueryDTO dto) {

        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getContentId()), ResultConfigEnum.HOMEWORK_ID_NOT_NULL.getDescription());
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getStudentId()), ResultConfigEnum.STUDENT_ID_NOT_NULL.getDescription());
        dto.setInProgress(HomeWorkRecordStatusEnum.IN_PROGRESS_YES.getCode());
        // 获取学生作业日志
        List<CourseHomeworkStudentInfoResultDTO> list = this.baseMapper.homeworkStudentInfoList(dto);
        // 判断为 0 未参与学生可以查看只是不能提交作业因此为0要判断
        CommonErrors.NOT_IMPLEMENTED.check(list.size() == 0 || list.size() == 1, "查询异常出现多个或未获取到");
        return list.size() == 0 ? null : list.get(0);
    }

    /**
     * 校验学生是否可提交作业
     *
     * @author dzy
     */
    private boolean checkSubmitFlag(Long contentId, Integer times, Long studentId) {
        LambdaQueryWrapper<CourseHomeworkRecordEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseHomeworkRecordEntity::getContentId, contentId);
        wrapper.eq(CourseHomeworkRecordEntity::getTimes, times);
        wrapper.eq(CourseHomeworkRecordEntity::getStudentId, studentId);
        List<Integer> taskStatus = new ArrayList<>();
        taskStatus.add(HomeWorkStudentStatusEnum.SUBMIT.getCode());
        taskStatus.add(HomeWorkStudentStatusEnum.APPROVED.getCode());
        wrapper.in(CourseHomeworkRecordEntity::getTaskStatus, taskStatus);
        List<CourseHomeworkRecordEntity> list = courseHomeworkRecordService.list(wrapper);
        if (CollectionUtils.isNotEmpty(list) && list.size() > 1) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 更新已读标志
     */
    private void updateIsRead(CourseHomeworkStudentLogUpdateDTO updateDTO) {
        if (updateDTO != null) {
            updateDTO.setIsRead(YesNoNumberEnum.YES.getCode());
            this.updateById(updateDTO);
        }
    }

    /**
     * 更新已读标志
     */
    private void updateHandStatus(CourseHomeworkStudentLogUpdateDTO updateDTO) {
        if (updateDTO != null) {
            updateDTO.setHandStatus(YesNoNumberEnum.NO.getCode());
            this.updateById(updateDTO);
        }
    }

    /**
     * 提交作业
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long insert(CourseHomeworkStudentLogCreateDTO dto) {

        Long userId = LoginHelper.getUserId();
        // 获取操作用户
        ClassStudentResultDTO operaStudent = R.as(classStudentClient.findByStudentId(dto.getClassId(), userId));
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(operaStudent), "未获取到学生信息");
        // 获取主学生信息
        ClassStudentResultDTO mainStudent = R.as(classStudentClient.findVirtualClassStudentByClassIdAndUserId(dto.getClassId(), userId));
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(mainStudent), "未获取到学生信息");

        // 提交作业数据
        dto.setStudentId(mainStudent.getStudentId());
        Long id = this.submitHomework(dto, operaStudent.getRelationship());

        // 更新学生作业日志信息
        this.refreshHomeworkAllTotal(dto.getContentId(), mainStudent.getStudentId(), dto.getTimes());

        // 发送系统通知
        Spring.committedAsync(() -> {
            assistantListen.submitSysChat(dto.getClassId(), dto.getContentId(), mainStudent.getStudentId(), dto.getTimes());
        });
        return id;
    }

    @Transactional(rollbackFor = Exception.class)
    public Long submitHomework(CourseHomeworkStudentLogCreateDTO dto, String relationship) {

        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getFiles()) || StringUtils.isNotEmpty(dto.getHandContent()), "作业提交文件和作业内容不能都为空");
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getContentId()), "作业ID不能为空");
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getTimes()), "作业轮数不能为空");

        // 判断作业文件大小
        if (Objects.nonNull(dto.getFiles())) {
            List<CourseHomeworkFileCreateDTO> fileList = dto.getFiles();
            BigDecimal totalSize = fileList.stream().map(CourseHomeworkFileCreateDTO::getSize).reduce(BigDecimal.ZERO, BigDecimal::add);
            CommonErrors.BAD_REQUEST.check(totalSize.compareTo(new BigDecimal(500 * 1024 * 1024)) <= 0, "文件总和大小不能超过500M");
        }

        // 校验作业是否被删除
        CourseHomeworkEntity homeworkEntity = courseHomeworkMapper.selectById(dto.getContentId());
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(homeworkEntity), MessageUtils.message("course.homework.id.not.exit"));

        // 判断是否可以超时提价作业
        if (Objects.equals(YesNoNumberEnum.NO.getCode(), homeworkEntity.getLimitStatus())) {
            CommonErrors.BAD_REQUEST.check(homeworkEntity.getEndTime().isAfter(LocalDateTime.now()), "超时禁止提交作业");
        }

        // 获取学生日志记录
        LambdaQueryWrapper<CourseHomeworkStudentLogEntity> wrapper = Queries.lambda();
        Queries.accept(dto.getContentId(), v -> wrapper.eq(CourseHomeworkStudentLogEntity::getContentId, v));
        Queries.accept(dto.getTimes(), v -> wrapper.eq(CourseHomeworkStudentLogEntity::getTimes, v));
        Queries.accept(dto.getStudentId(), v -> wrapper.eq(CourseHomeworkStudentLogEntity::getStudentId, v));
        CourseHomeworkStudentLogEntity studentLogEntity = this.baseMapper.selectOne(wrapper);

        //判断学生是否可以提交作业
        if (Objects.nonNull(studentLogEntity)) {
            // 获取 作业提价历史记录
            LambdaQueryWrapper<CourseHomeworkRecordEntity> recordWrapper = new LambdaQueryWrapper<>();
            recordWrapper.eq(CourseHomeworkRecordEntity::getContentId, dto.getContentId());
            recordWrapper.eq(CourseHomeworkRecordEntity::getStudentId, dto.getStudentId());
            recordWrapper.eq(CourseHomeworkRecordEntity::getTimes, dto.getTimes());
            List<Integer> recordStatusList = new ArrayList<>();
            recordStatusList.add(HomeWorkStudentStatusEnum.SUBMIT.getCode());
            recordStatusList.add(HomeWorkStudentStatusEnum.APPROVED.getCode());
            recordWrapper.in(CourseHomeworkRecordEntity::getTaskStatus, recordStatusList);
            List<CourseHomeworkRecordEntity> recordList = courseHomeworkRecordService.list(recordWrapper);
            // 提交中的作业大于两次不可再次提交作业
            if (CollectionUtils.isNotEmpty(recordList) && recordList.size() >= HomeworkConstants.SUBMIT_NUM) {
                CommonErrors.BAD_REQUEST.check(false, "提交中的作业仅可以有两份");
            }
        }

        // 更新作业提交信息
        if (Objects.nonNull(studentLogEntity)) {
            CourseHomeworkStudentLogEntity studentLog = new CourseHomeworkStudentLogEntity();
            studentLog.setId(studentLogEntity.getId());
            studentLog.setHandTimes(studentLogEntity.getHandTimes() + 1);
            // 判断作业是否已批 已批作业不更改作业状态
            if (Objects.equals(HomeWorkStudentStatusEnum.APPROVED.getCode(), studentLogEntity.getTaskStatus())) {
                studentLog.setHandStatus(YesNoNumberEnum.YES.getCode());
            } else {
                studentLog.setTaskStatus(HomeWorkStudentStatusEnum.SUBMIT.getCode());
                // 清空原 recordId记录
                studentLog.setRecordId(0L);
                // 校验用户提交状态
                studentLog.setSubmitStatus(checkSubmitTask(homeworkEntity.getEndTime()));
                // 更新提交时间
                studentLog.setHandTime(LocalDateTime.now());
                // 更新提交人信息
                studentLog.setHandRelationship(relationship);
            }
            this.baseMapper.updateById(studentLog);
        } else {
            dto.setTaskStatus(HomeWorkStudentStatusEnum.SUBMIT.getCode());
            dto.setSubmitStatus(checkSubmitTask(homeworkEntity.getEndTime()));
            dto.setHandTimes(1);
            studentLogEntity = courseHomeworkStudentLogConvert.create(dto);
            // 更新提交时间
            studentLogEntity.setHandTime(LocalDateTime.now());
            // 更新提交人信息
            studentLogEntity.setHandRelationship(relationship);
            // 保存日志记录
            this.save(studentLogEntity);
        }

        // 添加作业提交记录
        List<CourseHomeworkFileEntity> recordFileList = this.insertRecord(dto, relationship);
        // 生成作业文件切片信息
        Spring.committed(() -> sliceHomeworkFileService.updateHomeworkFileSlice(recordFileList));

        return studentLogEntity.getId();

    }

    /**
     * 添加作业提交记录
     * @operaRelationship 操作人与用户关系
     * @author dzy
     */
    @Transactional(rollbackFor = Exception.class)
    public List<CourseHomeworkFileEntity> insertRecord(CourseHomeworkStudentLogCreateDTO dto, String operaRelationship) {

        // 更新历史提交作业信息
        LambdaQueryWrapper<CourseHomeworkRecordEntity> recordWrapper = new LambdaQueryWrapper<>();
        recordWrapper.eq(CourseHomeworkRecordEntity::getContentId, dto.getContentId());
        recordWrapper.eq(CourseHomeworkRecordEntity::getTimes, dto.getTimes());
        recordWrapper.eq(CourseHomeworkRecordEntity::getStudentId, dto.getStudentId());
        List<CourseHomeworkRecordEntity> recordList = courseHomeworkRecordService.list(recordWrapper);
        recordList.forEach(item -> item.setInProgerss(HomeWorkRecordStatusEnum.IN_PROGRESS_NO.getCode()));
        courseHomeworkRecordService.updateBatchById(recordList);

        //添加新的作业记录
        Long recordId = identifierGenerator.nextId(null).longValue();
        CourseHomeworkRecordEntity recordEntity = new CourseHomeworkRecordEntity();
        recordEntity.setId(recordId);
        recordEntity.setContentId(dto.getContentId());
        recordEntity.setTimes(dto.getTimes());
        recordEntity.setStudentId(dto.getStudentId());
        recordEntity.setStudentRemark(dto.getStudentRemark());
        recordEntity.setHandTime(LocalDateTime.now());
        recordEntity.setHandContent(dto.getHandContent());
        recordEntity.setTaskStatus(HomeWorkStudentStatusEnum.SUBMIT.getCode());
        recordEntity.setOperaRelationship(operaRelationship);
        courseHomeworkRecordService.save(recordEntity);

        // 添加作业文件记录
        List<CourseHomeworkFileEntity> list = new ArrayList<>();
        // 判断文件是否为空 不为空添加文件记录
        if (Objects.nonNull(dto.getFiles())) {
            dto.getFiles().forEach(item -> {
                item.setRecordId(recordId);
                list.add(courseHomeworkFileConvert.create(item));
            });
            courseHomeworkFileService.saveBatch(list);
        }
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void refreshHomeworkAllTotal(Long contentId, Long studentId, Integer times) {
        // 获取学生日志记录
        CourseHomeworkStudentLogQueryDTO queryDTO = new CourseHomeworkStudentLogQueryDTO();
        queryDTO.setContentId(contentId);
        queryDTO.setStudentId(studentId);
        queryDTO.setTimes(times);
        CourseHomeworkStudentInfoResultDTO entity = this.findStudentInfo(queryDTO);
        if (Objects.nonNull(entity)) {
            // 更新参与状态
            this.parTake(entity.getId());
        }
    }

    private Integer checkSubmitTask(LocalDateTime endTime) {
        if (endTime.isBefore(LocalDateTime.now())) {
            long duration = Duration.between(endTime, LocalDateTime.now()).toDays();
            CommonErrors.NOT_ACCEPTABLE.check((duration <= HomeWorkStudentStatusEnum.SUBMIT_OVER_MAX_TIME.getCode()), MessageUtils.message("course.homework.overtime.fail"));
        }

        if (endTime.isBefore(LocalDateTime.now())) {
            return HomeWorkStudentStatusEnum.SUBMIT_OVER_TIME.getCode();
        } else {
            return HomeWorkStudentStatusEnum.SUBMIT_ON_TIME.getCode();
        }
    }

    /**
     * 根据id修改 数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateById(CourseHomeworkStudentLogUpdateDTO dto) {
        CourseHomeworkStudentLogEntity old = Optional.ofNullable(this.getById(dto.getId())).orElseThrow(() -> CommonErrors.NOT_FOUND.asException(ResultConfigEnum.DATA_NOT_EXIST.getDescription()));
        CourseHomeworkStudentLogEntity entity = courseHomeworkStudentLogConvert.update(dto);
        return this.updateById(entity);
    }

    /**
     * 判断更新学生作业提交记录信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean checkUpdate(CourseHomeworkStudentLogUpdateDTO dto) {
        CourseHomeworkStudentLogQueryDTO studentLogQueryDTO = new CourseHomeworkStudentLogQueryDTO();
        CourseHomeworkStudentInfoResultDTO studentLogResultDTO = this.findStudentInfo(studentLogQueryDTO);
        if (studentLogResultDTO == null) {
            CourseHomeworkStudentLogEntity studentLogEntity = new CourseHomeworkStudentLogEntity();
            studentLogEntity.setContentId(dto.getContentId());
            studentLogEntity.setTimes(dto.getTimes());
            studentLogEntity.setStudentId(dto.getStudentId());
            studentLogEntity.setHandTimes(1);
            this.save(studentLogEntity);
        } else {
            dto.setId(studentLogResultDTO.getId());
            dto.setHandTimes(studentLogResultDTO.getHandTimes() + 1);
            this.updateById(dto);
        }
        return true;
    }

    /**
     * 同步作业学生数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncStudent(CourseHomeworkStudentLogCreateDTO dto) {

        List<ClassStudentResultDTO> studentList = R.as(classStudentClient.studentListByClassId(dto.getClassId()));
        if (studentList.size() > 0) {
            List<Long> studentIds = studentList.stream().map(ClassStudentResultDTO::getStudentId).collect(Collectors.toList());
            CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(studentIds), "小组暂无成员");
            // 校验没有作业记录的学生
            List<CourseHomeworkStudentLogEntity> students = checkStudentInHomework(dto, studentIds);
            // 添加对应学生的作业记录
            if (Objects.nonNull(students) && students.size() > 0) {
                this.initHomeworkStudent(students);
            }
        }
    }

    /**
     * 新增班级学生作业数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertClassStudentLogBatch(List<CourseHomeworkEntity> homeworkEntityList) {

        List<Long> classIdList = homeworkEntityList.stream().map(CourseHomeworkEntity::getClassId).collect(Collectors.toList());

        // 获取多班级 主学生结合
        List<ClassStudentResultDTO> studentList = R.as(classStudentClient.findClassMasterStudentByClassIdList(classIdList));
        if (CollectionUtils.isEmpty(studentList)) {
            return;
        }

        // 构建学生作业数据
        List<CourseHomeworkStudentLogEntity> studentLogs = this.initBatchHomeworkStudentLog(homeworkEntityList, studentList);

        // 添加对应学生的作业记录
        this.initHomeworkStudent(studentLogs);

    }

    /**
     * 新增小组学生作业数据,小组作业不存在多班级
     */
    @Override
    public void insertGroupStudentLogBatch(List<CourseHomeworkEntity> homeworkEntityList) {
        CourseHomeworkEntity entity = homeworkEntityList.get(0);

        CommonErrors.BAD_REQUEST.check(StringUtils.isNotEmpty(entity.getGroupIds()), "小组id不能为空");
        List<Long> groupList = Arrays.stream(entity.getGroupIds().split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());

        List<ClassGroupStudentResultDTO> studentList = R.as(classGroupStudentClient.findStudentListByGroupIds(groupList));

        if (CollectionUtils.isEmpty(studentList)) {
            return;
        }

        // 构建学生作业数据
        List<CourseHomeworkStudentLogEntity> studentLogs = this.initBatchGroupHomeworkStudentLog(homeworkEntityList, studentList);

        // 添加对应学生的作业记录
        this.initHomeworkStudent(studentLogs);
    }

    /**
     * 初始化小组作业
     *
     * @param homeworkEntityList 作业实体列表
     * @return List<CourseHomeworkStudentLogEntity>
     */
    private List<CourseHomeworkStudentLogEntity> initBatchGroupHomeworkStudentLog(List<CourseHomeworkEntity> homeworkEntityList, List<ClassGroupStudentResultDTO> studentList) {

        List<CourseHomeworkStudentLogEntity> resultList = new ArrayList<>();
        this.addRepeatStudentHomework(homeworkEntityList);

        //基于多轮次的作业复制给学生，小组作业不涉及多班级
        homeworkEntityList.forEach(entity -> studentList.forEach(student -> {
            CourseHomeworkStudentLogEntity studentLogEntity = new CourseHomeworkStudentLogEntity();
            studentLogEntity.setStudentId(student.getStudentId());
            studentLogEntity.setContentId(entity.getId());
            studentLogEntity.setClassId(student.getClassId());
            studentLogEntity.setTimes(entity.getCurrRepeatDay());
            resultList.add(studentLogEntity);
        }));

        return resultList;
    }

    /**
     * /*     * 批量初始化学生作业日志，这里需要将多轮次的作业拆分出来，生成给学生
     *
     * @param homeworkEntityList 作业实体列表
     * @return List<CourseHomeworkStudentLogEntity>
     */
    private List<CourseHomeworkStudentLogEntity> initBatchHomeworkStudentLog(List<CourseHomeworkEntity> homeworkEntityList, List<ClassStudentResultDTO> studentList) {
        List<CourseHomeworkStudentLogEntity> studentLogEntityList = new ArrayList<>();
        this.addRepeatStudentHomework(homeworkEntityList);

        //基于多轮次的作业复制到学生
        homeworkEntityList.forEach(entity -> studentList.forEach(student -> {
            if (Objects.equals(entity.getClassId(), student.getClassId())) {
                CourseHomeworkStudentLogEntity studentLogEntity = new CourseHomeworkStudentLogEntity();
                studentLogEntity.setStudentId(student.getStudentId());
                studentLogEntity.setContentId(entity.getId());
                studentLogEntity.setClassId(student.getClassId());
                studentLogEntity.setTimes(entity.getCurrRepeatDay());
                studentLogEntityList.add(studentLogEntity);
            }
        }));

        return studentLogEntityList;
    }

    /**
     * 学生作业做多轮次处理
     *
     * @param homeworkEntityList
     */
    private void addRepeatStudentHomework(List<CourseHomeworkEntity> homeworkEntityList) {
        List<CourseHomeworkEntity> repeadHomeworkList = new ArrayList<>();
        homeworkEntityList.forEach(entity -> courseHomeworkService.addRepeatHomeworkList(repeadHomeworkList, entity));

        //将多轮次的作业追加到作业列表
        if (CollectionUtils.isNotEmpty(repeadHomeworkList)) {
            homeworkEntityList.addAll(repeadHomeworkList);
        }
    }

    /**
     * 同步作业学生数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncGroupStudent(CourseHomeworkStudentLogCreateDTO dto, String groupIds) {
        List<Long> groupList = Arrays.stream(groupIds.split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        List<ClassGroupStudentResultDTO> studentList = R.as(classGroupStudentClient.findStudentListByGroupIds(groupList));
        List<Long> studentIds = studentList.stream().map(ClassGroupStudentResultDTO::getStudentId).collect(Collectors.toList());
        CommonErrors.BAD_REQUEST.check(CollectionUtil.isNotEmpty(studentIds), "小组暂无成员");
        // 校验没有作业记录的学生
        List<CourseHomeworkStudentLogEntity> students = checkStudentInHomework(dto, studentIds);
        // 添加对应学生的作业记录
        this.initHomeworkStudent(students);
    }

    /**
     * 查询没有作业记录的日志学生
     */
    private List<CourseHomeworkStudentLogEntity> checkStudentInHomework(CourseHomeworkStudentLogCreateDTO dto, List<Long> studentIds) {
        CourseHomeworkStudentLogQueryDTO query = new CourseHomeworkStudentLogQueryDTO();
        query.setContentId(dto.getContentId());
        query.setTimes(dto.getTimes());
        LambdaQueryWrapper<CourseHomeworkStudentLogEntity> wrapper = wrapper(query);
        wrapper.in(CourseHomeworkStudentLogEntity::getStudentId, studentIds);
        List<CourseHomeworkStudentLogResultDTO> homeworkResultDTOS = this.baseMapper.selectDtoList(wrapper, courseHomeworkStudentLogConvert::convert);
        if (Objects.nonNull(homeworkResultDTOS) && homeworkResultDTOS.size() > 0) {
            List<Long> newList = studentIds.stream().filter(item -> homeworkResultDTOS.stream().allMatch(each -> !Objects.equals(item, each.getStudentId()))).collect(Collectors.toList());
            studentIds = newList;
        }
        // 转换ENTITY对象
        List<CourseHomeworkStudentLogEntity> list = studentIds.stream().map(v -> {
            CourseHomeworkStudentLogEntity studentLog = new CourseHomeworkStudentLogEntity();
            studentLog.setStudentId(v.longValue());
            studentLog.setContentId(dto.getContentId());
            studentLog.setClassId(dto.getClassId());
            studentLog.setTimes(dto.getTimes());
            return studentLog;
        }).collect(Collectors.toList());
        return list;
    }

    /**
     * 新增 数据
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean initHomeworkStudent(List<CourseHomeworkStudentLogEntity> list) {
        if (CollectionUtils.isEmpty(list)) {
            return true;
        }

        list.forEach(item -> {
            item.setTaskStatus(HomeWorkStudentStatusEnum.NOT_SUBMIT.getCode());
            item.setHandTimes(0);
        });

        //这一步本应该是不必要的，但是数据库里有脏数据，所以加了这一句
        List<CourseHomeworkStudentLogEntity> existingHomeworkList = this.findListByContentIdListAndStudentListAndTimes(list);
        if (!CollectionUtils.isEmpty(existingHomeworkList)) {
            List<CourseHomeworkStudentLogEntity> prepareSavedList = this.filteredExisted(list, existingHomeworkList);
            return this.saveOrUpdateBatch(prepareSavedList, 1500);
        } else {
            return this.saveOrUpdateBatch(list, 1500);

        }
    }

    private List<CourseHomeworkStudentLogEntity> findListByContentIdListAndStudentListAndTimes(List<CourseHomeworkStudentLogEntity> paramList) {
        QueryWrapper<CourseHomeworkStudentLogEntity> queryWrapper = new QueryWrapper<>();
        for (CourseHomeworkStudentLogEntity studentLogEntity : paramList) {
            queryWrapper.or(i -> i.eq("content_id", studentLogEntity.getContentId()).eq("student_id", studentLogEntity.getStudentId()).eq("times", studentLogEntity.getTimes()));
        }

        return this.baseMapper.selectList(queryWrapper);
    }

    /**
     * 过滤已发布的，这一步本应该是不必要的，但是数据库里有脏数据，所以加了这一句
     *
     * @param allList              总共需要发布的
     * @param existingHomeworkList 数据库已存在的
     * @return
     */
    private List<CourseHomeworkStudentLogEntity> filteredExisted(List<CourseHomeworkStudentLogEntity> allList, List<CourseHomeworkStudentLogEntity> existingHomeworkList) {

        Map<Integer, CourseHomeworkStudentLogEntity> prepareSavedMap = new HashMap<>();

        for (CourseHomeworkStudentLogEntity entity : allList) {
            prepareSavedMap.put(entity.hashCode(), entity);
        }

        existingHomeworkList.forEach(existingHomework -> {
            if (prepareSavedMap.containsKey(existingHomework.hashCode())) {
                prepareSavedMap.put(existingHomework.hashCode(), null);
            }
        });

        return prepareSavedMap.values().stream().filter(Objects::nonNull).collect(Collectors.toList());
    }

    /**
     * 根据学生id结合 催交 课程栏目作业数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean call(CourseHomeworkStudentLogQueryDTO dto) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getContentId()), MessageUtils.message("course.homework.id.not.blank"));
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getTimes()), MessageUtils.message("course.homework.times.not.blank"));

        // 校验作业是否可进行催交
        CourseHomeworkResultDTO homework = courseHomeworkService.findSimpleById(dto.getContentId());
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(homework), MessageUtils.message("course.homework.id.not.exit"));
        if (Objects.equals(YesNoNumberEnum.YES.getCode(), homework.getLimitStatus())) {
            LocalDateTime compTime = homework.getEndTime().plusDays(7L);
            CommonErrors.BAD_REQUEST.check(compTime.isAfter(LocalDateTime.now()), MessageUtils.message("course.homework.not.submit.is.valid"));
        } else {
            CommonErrors.BAD_REQUEST.check(homework.getEndTime().isAfter(LocalDateTime.now()), MessageUtils.message("course.homework.not.submit.is.valid"));
        }

        List<CourseHomeworkStudentLogResultDTO> list = this.find(dto);
        List<CourseHomeworkStudentLogEntity> updateDTOS = new ArrayList<>();
        Boolean callFlag = false;
        for (CourseHomeworkStudentLogResultDTO studentLogResultDTO : list) {
            // 未提交的学生才可以进行催交
            if (HomeWorkStudentStatusEnum.NOT_SUBMIT.getCode().equals(studentLogResultDTO.getTaskStatus()) || HomeWorkStudentStatusEnum.REPLUSE.getCode().equals(studentLogResultDTO.getTaskStatus())) {
                // 有催交学生添加催交标志
                if (!callFlag) {
                    callFlag = true;
                }
                // 校验学生是否可以催交
                CourseHomeworkStudentLogUpdateDTO studentLogUpdateDTO = new CourseHomeworkStudentLogUpdateDTO();
                studentLogUpdateDTO.setId(studentLogResultDTO.getId());
                studentLogUpdateDTO.setStudentId(studentLogResultDTO.getStudentId());
                studentLogUpdateDTO.setContentId(studentLogResultDTO.getContentId());
                studentLogResultDTO.setTimes(studentLogResultDTO.getTimes());
                if (Objects.isNull(studentLogResultDTO.getCalls()) || studentLogResultDTO.getCalls() == 0) {
                    studentLogUpdateDTO.setCalls(1);
                    studentLogUpdateDTO.setCallTime(LocalDateTime.now());
                    updateDTOS.add(courseHomeworkStudentLogConvert.update(studentLogUpdateDTO));
                } else {
                    //催交判断大于一分钟才进行催交
                    long minutesNum = Duration.between(studentLogResultDTO.getCallTime(), LocalDateTime.now()).toMinutes();
                    if (minutesNum >= HomeWorkStudentStatusEnum.CALL_MAX.getCode()) {
                        studentLogUpdateDTO.setCalls(studentLogResultDTO.getCalls() + 1);
                        studentLogUpdateDTO.setCallTime(LocalDateTime.now());
                        updateDTOS.add(courseHomeworkStudentLogConvert.update(studentLogUpdateDTO));
                    }
                }
            }
        }

        if (callFlag) {
            CommonErrors.BAD_REQUEST.check(updateDTOS.size() > 0, MessageUtils.message("course.homework.call.valid"));
        } else {
            CommonErrors.BAD_REQUEST.check(updateDTOS.size() > 0, MessageUtils.message("course.homework.student.not.empty"));
        }

        boolean flag = this.updateBatchById(updateDTOS);
        if (flag) {
            //新奇助手作业催交
            assistantListen.operaHomeworkStudent(dto.getContentId(), dto.getTimes(), updateDTOS, AssistantTypeEnum.CALL.getCode(), null);
        }
        return flag;
    }

    /**
     * 根据学生id结合 打回 课程栏目作业数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean repulse(List<CourseHomeworkStudentLogUpdateDTO> list) {
        List<CourseHomeworkStudentLogEntity> updateDTOS = new ArrayList<>();
        List<CourseHomeworkStudentLogEntity> assistantDTOS = new ArrayList<>();

        // 设置默认作业ID和作业轮数
        Long contentId = 0L;
        Integer times = 1;

        // 获取学生日志记录
        List<Long> ids = list.stream().map(v -> v.getId()).collect(Collectors.toList());
        LambdaQueryWrapper<CourseHomeworkStudentLogEntity> logWrapper = new LambdaQueryWrapper<>();
        logWrapper.in(CourseHomeworkStudentLogEntity::getId, ids);
        List<CourseHomeworkStudentLogEntity> logList = this.list(logWrapper);
        Map<Long, CourseHomeworkStudentLogEntity> logMap = logList.stream()
            .collect(Collectors.toMap(CourseHomeworkStudentLogEntity::getId, Function.identity()));
        // 遍历设置修改内容
        for (CourseHomeworkStudentLogUpdateDTO studentLogUpdateDTO : list) {
            CourseHomeworkStudentLogEntity old = logMap.get(studentLogUpdateDTO.getId());
            // 判断是否可以打回
            this.checkIsCanRepulse(old.getContentId(), old.getStudentId(), old.getTimes());
            // 赋值学生ID
            studentLogUpdateDTO.setStudentId(old.getStudentId());
            // 已提交、已阅、已批的学生才可以进行打回
            if (checkTaskStatusList().contains(old.getTaskStatus())) {
                // 打回次数值为空赋值0
                if (old.getRepulseTotal() == null) {
                    studentLogUpdateDTO.setRepulseTotal(0);
                }
                contentId = old.getContentId();
                studentLogUpdateDTO.setRepulseTotal(old.getRepulseTotal() + 1);
                // 学生当前状态 为 已批
                if (Objects.equals(HomeWorkStudentStatusEnum.APPROVED.getCode(), old.getTaskStatus())) {
                    // 判断打回的ID是否等于已批ID 等于 批阅记录ID 清空用户分数
                    if (Objects.equals(old.getRecordId(), studentLogUpdateDTO.getRecordId())) {
                        // 打回将分享置为 0
                        studentLogUpdateDTO.setShare(0);
                        // 打回将分数置为0
                        studentLogUpdateDTO.setStudentScore(new BigDecimal(0));
                        studentLogUpdateDTO.setRecordId(studentLogUpdateDTO.getRecordId());
                        studentLogUpdateDTO.setTaskStatus(HomeWorkStudentStatusEnum.REPLUSE.getCode());
                    } else {
                        studentLogUpdateDTO.setTaskStatus(HomeWorkStudentStatusEnum.APPROVED.getCode());
                    }
                }
                // 学生当前状态 为 已提交
                else {
                    // 判断学生是否有提交中的作业 重新赋值提交状态
                    CourseHomeworkRecordEntity entity = this.checkSubmitRecord(contentId, old.getStudentId(), times, studentLogUpdateDTO.getRecordId());
                    if (Objects.nonNull(entity)) {
                        studentLogUpdateDTO.setTaskStatus(HomeWorkStudentStatusEnum.SUBMIT.getCode());
                        studentLogUpdateDTO.setHandTime(entity.getCreateTime());
                        studentLogUpdateDTO.setHandRelationship(entity.getOperaRelationship());
                    } else {
                        studentLogUpdateDTO.setRecordId(studentLogUpdateDTO.getRecordId());
                        studentLogUpdateDTO.setTaskStatus(HomeWorkStudentStatusEnum.REPLUSE.getCode());
                    }
                }

                studentLogUpdateDTO.setHandStatus(YesNoNumberEnum.NO.getCode());
                updateDTOS.add(courseHomeworkStudentLogConvert.update(studentLogUpdateDTO));

                CourseHomeworkStudentLogEntity newStudentLog = courseHomeworkStudentLogConvert.update(studentLogUpdateDTO);
                newStudentLog.setRecordId(studentLogUpdateDTO.getRecordId());
                assistantDTOS.add(newStudentLog);
                // 更新提交记录
                updateRecord(old, studentLogUpdateDTO.getRecordId(), HomeWorkStudentStatusEnum.REPLUSE, null, null, studentLogUpdateDTO.getRepulseReason());
            }
        }

        boolean flag = this.updateBatchById(updateDTOS);

        if (flag) {
            assistantListen.operaHomeworkStudent(contentId, times, assistantDTOS, AssistantTypeEnum.REPULSE.getCode(), list.get(0).getRepulseReason());
        }

        return flag;
    }

    /**
     * 超时不可打回
     *
     * @param contentId 作业id
     * @return boolean
     */
    private boolean checkIsCanRepulse(Long contentId, Long studentId, Integer times) {
        // 判断 提交和批阅的数据是否大于两条
        List<CourseHomeworkRecordEntity> list = this.getSubmitRecord(contentId, studentId, times);
        if (CollectionUtils.isNotEmpty(list) && list.size() > 1) {
            return true;
        }
        // 判断是否超时允许提交
        CourseHomeworkEntity homeworkEntity = courseHomeworkMapper.selectById(contentId);
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(homeworkEntity), MessageUtils.message("course.homework.not.blank"));
        if (homeworkEntity.getEndTime().isBefore(LocalDateTime.now()) && Objects.equals(YesNoNumberEnum.NO.getCode(), homeworkEntity.getLimitStatus())) {
            throw CommonErrors.BAD_REQUEST.asException("已超出提交时间不可打回");
        }

        if (homeworkEntity.getEndTime().isBefore(LocalDateTime.now()) && Duration.between(homeworkEntity.getEndTime(), LocalDateTime.now()).toDays() > 7 && Objects.equals(YesNoNumberEnum.YES.getCode(), homeworkEntity.getLimitStatus())) {
            throw CommonErrors.BAD_REQUEST.asException("已超出提交时间不可打回");
        }
        return true;
    }

    /**
     * 根据学生id结合 已阅 课程栏目作业数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean readOver(List<CourseHomeworkStudentApproveDTO> list) {
        List<CourseHomeworkStudentLogEntity> updateDTOS = new ArrayList<>();
        for (CourseHomeworkStudentApproveDTO studentApproveDTO : list) {
            CourseHomeworkStudentLogUpdateDTO studentLogUpdateDTO = new CourseHomeworkStudentLogUpdateDTO();
            studentLogUpdateDTO.setId(studentApproveDTO.getId());
            studentApproveDTO.setIsMarked(studentApproveDTO.getIsMarked());
            studentApproveDTO.setTeacherComment(studentApproveDTO.getTeacherComment());
            CourseHomeworkStudentLogEntity old = this.getById(studentLogUpdateDTO.getId());
            // 已提交、已阅、已批的学生才可以进行已阅操作
            if (old != null && checkTaskStatusList().contains(old.getTaskStatus())) {
                studentLogUpdateDTO.setTaskStatus(HomeWorkStudentStatusEnum.READ_OVER.getCode());
                studentLogUpdateDTO.setStudentScore(new BigDecimal(0));
                updateDTOS.add(courseHomeworkStudentLogConvert.update(studentLogUpdateDTO));

                // 更新学生提交记录
                updateRecord(old, studentApproveDTO.getRecordId(), HomeWorkStudentStatusEnum.READ_OVER, studentApproveDTO.getTeacherComment(), null, null);
            }
        }
        return this.updateBatchById(updateDTOS);
    }

    /**
     * 根据学生id结合 已批 课程栏目作业数据
     */
    @Override
    public boolean approved(List<CourseHomeworkStudentApproveDTO> list) {

        // 获取批阅学生记录
        List<Long> ids = list.stream().map(v -> v.getId()).collect(Collectors.toList());
        LambdaQueryWrapper<CourseHomeworkStudentLogEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CourseHomeworkStudentLogEntity::getId, ids);
        List<CourseHomeworkStudentLogEntity> studentLog = this.baseMapper.selectList(wrapper);

        boolean flag = this.approvedHomework(list, studentLog);

        // 新奇助手 需校验提交状态 发送新消息
        if (flag) {
            Long contentId = 0L;
            Integer times = 1;

            // 根据ID获取所有批阅作业的日志记录
            List<Long> logIds = list.stream().map(CourseHomeworkStudentApproveDTO::getId).collect(Collectors.toList());
            List<CourseHomeworkStudentLogEntity> entities = this.baseMapper.selectBatchIds(logIds);

            // 遍历设置需要发送的助手集合
            List<CourseHomeworkStudentLogEntity> logEntities = new ArrayList<>();
            for (CourseHomeworkStudentApproveDTO item : list) {
                CourseHomeworkStudentLogEntity entity = entities.stream().filter(v -> Objects.equals(item.getId(), v.getId())).findFirst().orElse(null);
                if (Objects.nonNull(entity)) {
                    contentId = entity.getContentId();
                    times = entity.getTimes();
                    entity.setStudentScore(MathUtils.stripTrailingZeros(item.getStudentScore(), 1));
                    logEntities.add(entity);
                }
            }
            if (logEntities.size() > 0) {
                assistantListen.operaHomeworkStudent(contentId, times, logEntities, AssistantTypeEnum.SCORE.getCode(), null);
            }
        }
        return flag;
    }

    /**
     * 批阅学生提交作业业务
     * @param list 批阅内容
     * @param logList 批阅学生的记录
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean approvedHomework(List<CourseHomeworkStudentApproveDTO> list, List<CourseHomeworkStudentLogEntity> logList) {

        List<CourseHomeworkStudentLogEntity> updateDTOS = new ArrayList<>();
        for (CourseHomeworkStudentApproveDTO studentApproveDTO : list) {
            // 获取单个日志信息
            CourseHomeworkStudentLogEntity log = logList.stream().filter(item ->
                Objects.equals(studentApproveDTO.getId(), item.getId())).findFirst().orElse(null);

            CourseHomeworkStudentLogUpdateDTO studentLogUpdateDTO = new CourseHomeworkStudentLogUpdateDTO();
            studentLogUpdateDTO.setId(studentApproveDTO.getId());

            // 已提交、已阅、已批的学生才可以进行已批操作
            if (Objects.nonNull(log) && checkTaskStatusList().contains(log.getTaskStatus())) {
                CommonErrors.BAD_REQUEST.check(Objects.nonNull(studentApproveDTO.getStudentScore()), ResultConfigEnum.STUDENT_SCORE_NOT_NULL.getDescription());
                studentLogUpdateDTO.setTaskStatus(4);
                studentLogUpdateDTO.setStudentScore(studentApproveDTO.getStudentScore());
                studentLogUpdateDTO.setRecordId(studentApproveDTO.getRecordId());
                // 校验批阅的是否是最新提交的作业
                if (this.checkNewSubmitRecord(log.getContentId(), log.getStudentId(), log.getTimes(), studentApproveDTO.getRecordId())) {
                    studentLogUpdateDTO.setHandStatus(YesNoNumberEnum.NO.getCode());
                }
                // 更新记录
                log.setStudentScore(studentApproveDTO.getStudentScore());
                updateRecord(log, studentApproveDTO.getRecordId(), HomeWorkStudentStatusEnum.APPROVED, studentApproveDTO.getTeacherComment(), studentApproveDTO.getVideos(), null);

                //添加日志修改信息
                studentLogUpdateDTO.setHandTime(log.getHandTime());
                studentLogUpdateDTO.setHandRelationship(log.getHandRelationship());
                updateDTOS.add(courseHomeworkStudentLogConvert.update(studentLogUpdateDTO));
            }
        }

        return this.updateBatchById(updateDTOS);
    }

    /**
     * 老师评语
     */
    @Override
    public boolean teachComment(List<CourseHomeworkStudentApproveDTO> list) {
        CommonErrors.BAD_REQUEST.check(list != null && list.size() > 0, "请求参数不能为空");
        // 老师评语长度判断
        if (Objects.nonNull(list.get(0).getTeacherComment())) {
            CommonErrors.BAD_REQUEST.check(list.get(0).getTeacherComment().length() <= 300, MessageUtils.message("course.content.teacherComment.length.valid"));
        }
        List<CourseHomeworkStudentLogEntity> updateDTOS = new ArrayList<>();
        for (CourseHomeworkStudentApproveDTO studentApproveDTO : list) {
            CourseHomeworkStudentLogEntity old = this.getById(studentApproveDTO.getId());
            // 已提交、已阅、已批的学生才可以进行评语
            if (old != null && checkTaskStatusList().contains(old.getTaskStatus())) {
                // 更新老师评语
                updateTeachComment(old, studentApproveDTO);
            }
        }
        return true;
    }

    /**
     * 判断是否批阅的是最新提交的作业
     * @author dzy
     */
    private boolean checkNewSubmitRecord(Long contentId, Long studentId, Integer times, Long recordId) {
        List<CourseHomeworkRecordEntity> list = this.getSubmitRecord(contentId, studentId, times);
        return Objects.equals(list.get(0).getId(), recordId);
    }

    /**
     * 获取已批已交的作业记录
     * @author dzy
     */
    private List<CourseHomeworkRecordEntity> getSubmitRecord(Long contentId, Long studentId, Integer times) {
        LambdaQueryWrapper<CourseHomeworkRecordEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseHomeworkRecordEntity::getContentId, contentId);
        wrapper.eq(CourseHomeworkRecordEntity::getStudentId, studentId);
        wrapper.eq(CourseHomeworkRecordEntity::getTimes, times);
        List<Integer> statusList = new ArrayList<>();
        statusList.add(HomeWorkStudentStatusEnum.SUBMIT.getCode());
        statusList.add(HomeWorkStudentStatusEnum.APPROVED.getCode());
        wrapper.in(CourseHomeworkRecordEntity::getTaskStatus, statusList);
        return courseHomeworkRecordService.list(wrapper);
    }

    /**
     * 判断是否有提交中和批阅的作业
     * @author dzy
     */
    private CourseHomeworkRecordEntity checkSubmitRecord(Long contentId, Long studentId, Integer times, Long recordId) {
        LambdaQueryWrapper<CourseHomeworkRecordEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseHomeworkRecordEntity::getContentId, contentId);
        wrapper.eq(CourseHomeworkRecordEntity::getStudentId, studentId);
        wrapper.eq(CourseHomeworkRecordEntity::getTimes, times);
        wrapper.ne(CourseHomeworkRecordEntity::getId, recordId);
        wrapper.orderByDesc(CourseHomeworkRecordEntity::getCreateTime);
        List<Integer> statusList = new ArrayList<>();
        statusList.add(HomeWorkStudentStatusEnum.SUBMIT.getCode());
        statusList.add(HomeWorkStudentStatusEnum.APPROVED.getCode());
        wrapper.in(CourseHomeworkRecordEntity::getTaskStatus, statusList);
        List<CourseHomeworkRecordEntity> list = courseHomeworkRecordService.list(wrapper);
        return CollectionUtils.isNotEmpty(list) ? list.get(0) : null;
    }

    /**
     * 更新学生提交记录及评语等
     *
     * @param old            学生作业
     * @param taskStatus     状态
     * @param teacherComment 老师评语
     * @param repulseReason  打回原因
     */
    private void updateRecord(CourseHomeworkStudentLogEntity old, Long recordId, HomeWorkStudentStatusEnum taskStatus, String teacherComment, String videos, String repulseReason) {
        CourseHomeworkRecordResultDTO recordResultDTO;
        if (Objects.nonNull(recordId)) {
            recordResultDTO = courseHomeworkRecordService.findById(recordId);
        } else {
            // 兼容旧接口不传RecordID
            CourseHomeworkRecordQueryDTO recordQueryDTO = new CourseHomeworkRecordQueryDTO();
            recordQueryDTO.setContentId(old.getContentId());
            recordQueryDTO.setTimes(old.getTimes());
            recordQueryDTO.setStudentId(old.getStudentId());
            recordQueryDTO.setInProgress(HomeWorkRecordStatusEnum.IN_PROGRESS_YES.getCode());
            recordResultDTO = courseHomeworkRecordService.findByParam(recordQueryDTO);
        }

        // 修改 批阅作业记录的数据
        if (Objects.nonNull(recordResultDTO)) {
            LambdaUpdateWrapper<CourseHomeworkRecordEntity> wrapper = new LambdaUpdateWrapper<>();
            wrapper.set(CourseHomeworkRecordEntity::getTaskStatus, taskStatus.getCode()).eq(CourseHomeworkRecordEntity::getId, recordResultDTO.getId());
            wrapper.set(CourseHomeworkRecordEntity::getTeacherComment, teacherComment).eq(CourseHomeworkRecordEntity::getId, recordResultDTO.getId());
            if (Objects.equals(HomeWorkStudentStatusEnum.APPROVED, taskStatus)) {
                wrapper.set(CourseHomeworkRecordEntity::getStudentScore, old.getStudentScore()).eq(CourseHomeworkRecordEntity::getId, recordResultDTO.getId());
            }
            wrapper.set(CourseHomeworkRecordEntity::getVideos, videos).eq(CourseHomeworkRecordEntity::getId, recordResultDTO.getId());
            wrapper.set(CourseHomeworkRecordEntity::getRepulseReason, repulseReason).eq(CourseHomeworkRecordEntity::getId, recordResultDTO.getId());
            courseHomeworkRecordService.update(wrapper);
            old.setHandTime(recordResultDTO.getCreateTime());
            old.setHandRelationship(recordResultDTO.getOperaRelationship());
        }

    }

    private void updateTeachComment(CourseHomeworkStudentLogEntity old, CourseHomeworkStudentApproveDTO studentApproveDTO) {
        CourseHomeworkRecordResultDTO recordResultDTO = courseHomeworkRecordService.findById(studentApproveDTO.getRecordId());
        if (recordResultDTO != null) {
            LambdaUpdateWrapper<CourseHomeworkRecordEntity> wrapper = new LambdaUpdateWrapper();
            wrapper.set(CourseHomeworkRecordEntity::getTeacherComment, studentApproveDTO.getTeacherComment())
                .eq(CourseHomeworkRecordEntity::getId, recordResultDTO.getId());
            courseHomeworkRecordService.update(wrapper);
        }
    }

    @Override
    public List<String> historyComment(CourseHomeworkStudentBaseDTO dto) {
        CourseHomeworkRecordQueryDTO recordQueryDTO = new CourseHomeworkRecordQueryDTO();
        recordQueryDTO.setContentId(dto.getContentId());
        recordQueryDTO.setTimes(dto.getTimes());
        return courseHomeworkRecordService.findHistoryComment(recordQueryDTO);
    }

    //判断是否可以进行打回、已阅、已批操作状态List集合
    private List<Integer> checkTaskStatusList() {
        List<Integer> checkStudentStatusList = new ArrayList<>();
        checkStudentStatusList.add(HomeWorkStudentStatusEnum.SUBMIT.getCode());
        checkStudentStatusList.add(HomeWorkStudentStatusEnum.READ_OVER.getCode());
        checkStudentStatusList.add(HomeWorkStudentStatusEnum.APPROVED.getCode());
        return checkStudentStatusList;
    }

    /**
     * 根据学生记录Id 分享
     */
    @Override
    public boolean share(CourseHomeworkStudentLogShareDTO dto) {
        CommonErrors.BAD_REQUEST.check(dto != null, "为获取到请求参数");
        LambdaUpdateWrapper<CourseHomeworkStudentLogEntity> wrapper = new LambdaUpdateWrapper();
        wrapper.set(CourseHomeworkStudentLogEntity::getShare, HomeWorkStudentStatusEnum.IS_SHARE_YES.getCode()).set(CourseHomeworkStudentLogEntity::getSharetitle, dto.getSharetitle()).set(CourseHomeworkStudentLogEntity::getIsReviewed, dto.getIsReviewed()).set(CourseHomeworkStudentLogEntity::getAnonymous, dto.getAnonymous()).eq(CourseHomeworkStudentLogEntity::getId, dto.getId());
        return this.update(wrapper);
    }

    /**
     * 学生查询 分享作业
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<CourseHomeworkStudentInfoResultDTO> findShare(CourseHomeworkStudentLogQueryDTO dto) {
        dto.setStudentId(LoginHelper.getUserId());
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getContentId()), ResultConfigEnum.HOMEWORK_ID_NOT_NULL.getDescription());
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getTimes()), ResultConfigEnum.HOMEWORK_TIMES_NOT_NULL.getDescription());
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getStudentId()), ResultConfigEnum.STUDENT_ID_NOT_NULL.getDescription());

        // 校验作业是否被删除
        CourseHomeworkEntity entity = courseHomeworkMapper.selectById(dto.getContentId());
        CommonErrors.NOT_DATA.check(Objects.nonNull(entity), MessageUtils.message("course.homework.id.not.exit"));

        ClassStudentResultDTO classStudentResultDTO = R.as(classStudentClient.findByStudentId(entity.getClassId(), LoginHelper.getUserId()));
        CommonErrors.NOT_DATA.check(Objects.nonNull(classStudentResultDTO), MessageUtils.message("学生不存在"));
        List<CourseHomeworkStudentInfoResultDTO> resultList = new ArrayList<>();

        // 查询已分享的作业信息
        dto.setShare(HomeWorkStudentStatusEnum.IS_SHARE_YES.getCode());
        dto.setStudentId(null);
        List<CourseHomeworkStudentInfoResultDTO> sharedList = this.baseMapper.homeworkStudentInfoList(dto);
        if (Objects.equals(YesNoEnum.YES.ordinal(), classStudentResultDTO.getIsTeacher())) {
            resultList.addAll(sharedList);
        } else {

            // 查询学生提交的作业信息
            dto.setStudentId(LoginHelper.getUserId());
            CourseHomeworkStudentInfoResultDTO studentLogResultDTO = this.findByParam(dto);

            sharedList.forEach(item -> {
                // 判断 查看分享作业 状态 (0:未批阅可查看 1:已批阅可查看)
                if (Objects.equals(YesNoNumberEnum.NO.getCode(), item.getIsReviewed())) {
                    resultList.add(item);
                } else {
                    if (Objects.nonNull(studentLogResultDTO) && Objects.nonNull(studentLogResultDTO.getTaskStatus())
                        && Objects.equals(HomeWorkStudentStatusEnum.APPROVED.getCode(), studentLogResultDTO.getTaskStatus())) {
                        resultList.add(item);
                    }
                }
            });
        }

        // 获取分享作业对应学生提交信息
        if (CollectionUtils.isNotEmpty(resultList)) {
            List<Long> studentIds = resultList.stream().map(CourseHomeworkStudentInfoResultDTO::getStudentId).collect(Collectors.toList());
            LambdaQueryWrapper<CourseHomeworkRecordEntity> recordWrapper = new LambdaQueryWrapper<>();
            recordWrapper.eq(CourseHomeworkRecordEntity::getContentId, dto.getContentId());
            recordWrapper.eq(CourseHomeworkRecordEntity::getTimes, dto.getTimes());
            // 获取已批 或 已提交的数据
            List<Integer> taskStatusList = new ArrayList<>();
            taskStatusList.add(HomeWorkStudentStatusEnum.SUBMIT.getCode());
            taskStatusList.add(HomeWorkStudentStatusEnum.APPROVED.getCode());
            recordWrapper.in(CourseHomeworkRecordEntity::getTaskStatus, taskStatusList);

            recordWrapper.in(CourseHomeworkRecordEntity::getStudentId, studentIds);
            recordWrapper.orderByDesc(CourseHomeworkRecordEntity::getCreateTime);
            List<CourseHomeworkRecordEntity> recordList = courseHomeworkRecordService.list(recordWrapper);
            if (CollectionUtils.isEmpty(recordList)) {
                return resultList;
            }

            // 校验学生分享时那一次作业
            List<CourseHomeworkRecordEntity> newRecordList = this.getStudentShare(recordList, sharedList);
            if (CollectionUtils.isEmpty(newRecordList)) {
                return resultList;
            }

            List<CourseHomeworkRecordResultDTO> recordResultList = courseHomeworkRecordConvert.convert(newRecordList);

            // 获取学生分享作业记录
            recordResultList.forEach(item -> {
                List<CourseHomeworkFileResultDTO> fileList = courseHomeworkFileService.findByRecordId(item.getId());
                item.setList(fileList);
            });

            // 匹配数据
            resultList.forEach(item -> {
                recordResultList.forEach(record -> {
                    if (Objects.equals(item.getStudentId(), record.getStudentId())) {
                        item.setRecord(record);
                    }
                });
            });
        }

        return resultList;
    }

    /**
     * 获取分享作业时那一次
     */
    private List<CourseHomeworkRecordEntity> getStudentShare(List<CourseHomeworkRecordEntity> recordList, List<CourseHomeworkStudentInfoResultDTO> sharedList) {
        // 遍历每个学生的提交记录
        Map<Long, List<CourseHomeworkRecordEntity>> map = recordList.stream().collect(Collectors.groupingBy(CourseHomeworkRecordEntity::getStudentId));
        // 遍历学生记录 和 批阅提交记录
        Map<Long, List<CourseHomeworkStudentInfoResultDTO>> logMap = sharedList.stream().collect(Collectors.groupingBy(CourseHomeworkStudentInfoResultDTO::getStudentId));
        // 校验 分享作业时那次提交
        List<CourseHomeworkRecordEntity> newRecordList = new ArrayList<>();
        for (Long key : map.keySet()) {
            List<CourseHomeworkRecordEntity> studentRecordList = map.get(key);
            // 获取已批数据
            List<CourseHomeworkRecordEntity> approveList = studentRecordList.stream().filter(v ->
                Objects.equals(HomeWorkStudentStatusEnum.APPROVED.getCode(),v.getTaskStatus())).collect(Collectors.toList());
            Long recordId = logMap.get(key).get(0).getRecordId();
            // 已批不为空 分享作业显示已批那一次
            if (CollectionUtils.isNotEmpty(approveList) && Objects.nonNull(recordId)) {
                // 校验是否有已批作业 跟 提交记录中的 记录ID一致 一致显示已批作业 不一致显示最新作业
                CourseHomeworkRecordEntity recordEntity = approveList.stream().filter(v -> Objects.equals(recordId, v.getId()))
                    .collect(Collectors.toList()).stream().findFirst().orElse(null);
                if (Objects.nonNull(recordEntity)) {
                    newRecordList.add(recordEntity);
                } else {
                    newRecordList.add(studentRecordList.get(0));
                }
            } else {
                // 不存在已批数据 或 记录中没有 批阅记录ID 显示最新作业
                newRecordList.add(studentRecordList.get(0));
            }
        }
        return newRecordList;
    }

    /**
     * 已参与未参与列表
     */
    @Override
    public List<CourseHomeworkStudentPartakeResultDTO> partakeList(CourseHomeworkStudentLogQueryDTO dto) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getContentId()), "作业ID不能为空");
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getTimes()), "作业轮数不能为空");
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getIsPartake()), "参与参数不能为空");
        return this.baseMapper.homeworkStudentPartakeList(dto);
    }

    /**
     * 修改学生参与状态
     */
    @Override
    public boolean parTake(Long id) {
        CourseHomeworkStudentLogEntity entity = new CourseHomeworkStudentLogEntity();
        entity.setId(id);
        entity.setIsPartake(1);
        return this.updateById(entity);
    }

    /**
     * 查询作业学生最大分数
     */
    @Override
    public BigDecimal homeworkMaxStudentScore(Long contentId) {
        return this.baseMapper.homeworkMaxStudentScore(contentId);
    }

    /**
     * 查询学生最后一次提交
     *
     * @return
     */
    @Override
    public CourseHomeworkStudentLogEntity getLast(Long contentId, Long studentId, Long classId) {
        LambdaQueryWrapper<CourseHomeworkStudentLogEntity> wrapper = new LambdaQueryWrapper();
        wrapper.eq(CourseHomeworkStudentLogEntity::getContentId, contentId);
        wrapper.eq(CourseHomeworkStudentLogEntity::getClassId, classId);
        wrapper.eq(CourseHomeworkStudentLogEntity::getStudentId, studentId);
        wrapper.orderByDesc(CourseHomeworkStudentLogEntity::getCreateTime);
        wrapper.last("limit  1");
        return baseMapper.selectOne(wrapper);
    }

    /**
     * 根据作业id和学生列表查询学生作业记录，这个记录包含了单个作业的多个轮次的记录
     *
     * @param contentId  作业id
     * @param studentIds 学生id列表
     * @return
     */
    @Override
    public List<CourseHomeworkStudentLogEntity> findByContentIdAndStudentIds(Long contentId, Collection<Long> studentIds) {
        LambdaQueryWrapper<CourseHomeworkStudentLogEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseHomeworkStudentLogEntity::getContentId, contentId);
        wrapper.in(CourseHomeworkStudentLogEntity::getStudentId, studentIds);
        return baseMapper.selectList(wrapper);
    }

    @Override
    public long homeworkStudentTotal(CourseHomeworkStudentLogQueryDTO dto) {
        return baseMapper.homeworkStudentTotal(dto);
    }

    /**
     * 删除多余的轮数
     */
    @Override
    public boolean deleteByHomework(CourseHomeworkEntity entity) {
        return this.baseMapper.deleteByHomework(entity);
    }

    @Override
    public List<CourseHomeworkStudentLogResultDTO> studentRepeatList(CourseHomeworkStudentDetailDTO dto) {
        //查询出第一轮的作业和已提交的作业
        List<CourseHomeworkStudentLogResultDTO> studentRepeatList = this.baseMapper.studentRepeatList(dto);
        if (CollectionUtils.isNotEmpty(studentRepeatList)) {
            Optional<CourseHomeworkStudentLogResultDTO> optional = studentRepeatList.stream().max(Comparator.comparingInt(CourseHomeworkStudentLogResultDTO::getTimes));

            if (optional.isPresent()) {
                CourseHomeworkStudentLogResultDTO maxTimeHomework = optional.get();
                boolean hasNextTime = maxTimeHomework.getRepeatDay() > maxTimeHomework.getTimes();
                boolean isAfter = !Objects.isNull(maxTimeHomework.getHandTime()) && LocalDate.now().isAfter(maxTimeHomework.getHandTime().toLocalDate());
                if (hasNextTime && isAfter) {
                    dto.setTimes(maxTimeHomework.getTimes() + 1);
                    CourseHomeworkStudentLogResultDTO nextTimeHomework = this.baseMapper.studentRepeatNext(dto);
                    if (Objects.nonNull(nextTimeHomework)) {
                        studentRepeatList.add(nextTimeHomework);
                    }
                }
            }
        }

        return studentRepeatList;
    }

    @Override
    public List<Integer> studentRepeatSelect(CourseHomeworkStudentDetailDTO dto) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getContentId()), "作业ID不能为空");
        List<CourseHomeworkStudentLogResultDTO> repeatList = this.studentRepeatList(dto);
        if (CollectionUtils.isEmpty(repeatList)) {
            return Collections.emptyList();
        }

        List<Integer> selectList = new ArrayList<>();
        for (int i = 1; i <= repeatList.size(); i++) {
            selectList.add(i);
        }

        return selectList;
    }

    @Override
    public List<Integer> teacherRepeatSelect(Long contentId) {
        CourseHomeworkResultDTO homeworkResultDTO = courseHomeworkService.findSimpleById(contentId);
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(homeworkResultDTO), "作业不存在");

        List<Integer> selectList = new ArrayList<>();
        for (int i = 1; i <= homeworkResultDTO.getRepeatDay(); i++) {
            selectList.add(i);
        }

        return selectList;
    }

    @Override
    public void cancelShare(Long studentHomeworkId) {
        CourseHomeworkStudentLogEntity entity = this.baseMapper.selectById(studentHomeworkId);
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(entity), "学生作业已被删除");

        ClassStudentResultDTO classStudentResultDTO = R.as(classStudentClient.findByStudentId(entity.getClassId(), LoginHelper.getUserId()));
        CommonErrors.NOT_DATA.check(Objects.nonNull(classStudentResultDTO), MessageUtils.message("老师不存在"));
        CommonErrors.NOT_DATA.check(Objects.equals(YesNoEnum.YES.ordinal(), classStudentResultDTO.getIsTeacher()), MessageUtils.message("只有老师才可以取消分享"));

        entity.setShare(YesNoEnum.NO.ordinal());
        this.baseMapper.updateById(entity);
    }

    @Override
    public Integer findSharedCount(CourseHomeworkStudentLogQueryDTO query, Integer taskStatus) {
        LambdaQueryWrapper<CourseHomeworkStudentLogEntity> wrapper = new LambdaQueryWrapper<>();
        Queries.accept(query.getContentId(), v -> wrapper.eq(CourseHomeworkStudentLogEntity::getContentId, v));
        Queries.accept(query.getTimes(), v -> wrapper.eq(CourseHomeworkStudentLogEntity::getTimes, v));
        Queries.accept(query.getShare(), v -> wrapper.eq(CourseHomeworkStudentLogEntity::getShare, v));
        List<CourseHomeworkStudentLogEntity> list = list(wrapper);
        if (!Objects.equals(HomeWorkStudentStatusEnum.APPROVED.getCode(), taskStatus)) {
            list.forEach(item -> {
                if (Objects.equals(YesNoNumberEnum.YES.getCode(), item.getIsReviewed())) {
                    list.remove(item);
                }
            });
        }
        return Math.toIntExact(list.size());
    }

}
